package com.laomo.lib_music;

import android.content.Context;
import android.media.MediaPlayer;
import android.media.audiofx.Visualizer;
import android.net.Uri;
import android.os.Handler;

import java.util.ArrayList;
import java.util.List;

/**
 * 类说明：
 *
 * @author laomo
 * @date 2024/7/30 14:00
 */
public class MusicPlayManager implements Visualizer.OnDataCaptureListener {
    private static MusicPlayManager instance;
    private MediaPlayer mMediaPlayer;
    private Visualizer mVisualizer;
    private Handler mHandler = new Handler();
    private float volume = 1.0f;

    private OnMusicPlayListener mOnMusicPlayListener;

    public static MusicPlayManager getInstance() {
        if (instance == null) {
            synchronized (MusicPlayManager.class) {
                if (instance == null) {
                    instance = new MusicPlayManager();
                }
            }
        }
        return instance;
    }

    private MusicPlayManager() {
        initMediaPlayer();
    }

    void initMediaPlayer() {
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setVolume(this.volume, this.volume);
        initVisualizer();
        mMediaPlayer.setOnCompletionListener(mp -> {
            mVisualizer.setEnabled(false);
            stopGetTime();
            if (mOnMusicPlayListener != null) {
                mOnMusicPlayListener.onPlayComplete();
            }
        });
    }


    void initVisualizer() {
        if (mVisualizer != null) {
            mVisualizer.setEnabled(false);
            mVisualizer.release();
        }
        mVisualizer = new Visualizer(mMediaPlayer.getAudioSessionId());
        mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
        mVisualizer.setDataCaptureListener(this, Visualizer.getMaxCaptureRate() / 2, false, true);
        mVisualizer.setScalingMode(Visualizer.SCALING_MODE_NORMALIZED);
    }

    public void setOnMusicPlayListener(OnMusicPlayListener onMusicPlayListener) {
        mOnMusicPlayListener = onMusicPlayListener;
    }

    private Runnable mGetPlayTime = new Runnable() {
        @Override
        public void run() {
            int p = mMediaPlayer.getCurrentPosition();
            if (mOnMusicPlayListener != null) {
                mOnMusicPlayListener.onProgress(p);
            }
            mHandler.postDelayed(mGetPlayTime, 300);
        }
    };

    private void startGetTime() {
        mHandler.post(mGetPlayTime);
    }

    private void stopGetTime() {
        mHandler.removeCallbacks(mGetPlayTime);
    }


    public void startPlay(String path) {
        try {
            mMediaPlayer.setDataSource(path);
            mMediaPlayer.prepare();
            if (mOnMusicPlayListener != null) {
                mOnMusicPlayListener.onStartPlay();
            }
            mMediaPlayer.start();
            startGetTime();
            mVisualizer.setEnabled(true);
        } catch (Exception e) {
            stopGetTime();
            mVisualizer.setEnabled(false);
        }
    }

    public void startPlay(Context context, Uri uri) {
        try {
            stopPlay();
            mMediaPlayer.setDataSource(context, uri);
            mMediaPlayer.prepare();
            if (mOnMusicPlayListener != null) {
                mOnMusicPlayListener.onStartPlay();
            }
            mMediaPlayer.start();
            startGetTime();
            mVisualizer.setEnabled(true);
        } catch (Exception e) {
            stopGetTime();
            mVisualizer.setEnabled(false);
        }
    }

    //继续播放
    public void continuePlay() {
        if (!mMediaPlayer.isPlaying()) {
            mMediaPlayer.start();
            mVisualizer.setEnabled(true);
            if (mOnMusicPlayListener != null) {
                mOnMusicPlayListener.onStartPlay();
            }
        }
    }

    public void seekTo(int position) {
        mMediaPlayer.seekTo(position);
        /*if (mOnMusicPlayListener != null) {
            mOnMusicPlayListener.onProgress(position);
        }*/
        continuePlay();
    }

    public void setVolume(float volume) {
        this.volume = volume;
        if (mMediaPlayer != null) {
            mMediaPlayer.setVolume(this.volume, this.volume);
        }
    }

    public void pausePlay() {
        if (mMediaPlayer.isPlaying()) {
            mMediaPlayer.pause();
            mVisualizer.setEnabled(false);
            if (mOnMusicPlayListener != null) {
                mOnMusicPlayListener.onPausePlay();
            }
        }
    }

    public void stopPlay() {
        mMediaPlayer.stop();
        mMediaPlayer.release();

        stopGetTime();
        if (mOnMusicPlayListener != null) {
            mOnMusicPlayListener.onPlayComplete();
        }
        initMediaPlayer();
    }

    @Override
    public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
        if (mOnMusicPlayListener != null) {
            mOnMusicPlayListener.onWaveFormDataCapture(waveform);
        }
    }

    @Override
    public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
        byte[] fft2 = castFft(fft);
        if (mOnMusicPlayListener != null) {
            mOnMusicPlayListener.onFftDataCapture(fft2);
        }
    }


    public static final byte[] castFft(byte[] fft){
        // 得到频谱数据
        byte[] spectrum = new byte[fft.length / 2];
        // 转换为幅度
        for (int i = 0; i < spectrum.length; i++) {
            Double magnitude = Math.hypot(fft[2*i], fft[2*i+1]);
            if (magnitude < 0) {
                spectrum[i] = 0;
            } else if (magnitude > 127) {
                spectrum[i] = 127 & 0xFF;
            } else {
                spectrum[i] = magnitude.byteValue();
            }
        }

        byte[] tmp = spectrum;

        List<Byte> list = new ArrayList<>();
        for(int i = 0;i<48;i++){
            list.add(tmp[i]);
        }

        //Log.d("lsflsddf",new Gson().toJson(list));

        byte[] fft2 = new byte[list.size()];
        for(int i = 0;i<list.size();i++){
            fft2[i] = list.get(i);
        }

        return fft2;
    }
}
